using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Collections;
using System.Drawing;
using System.Drawing.Imaging;
using System.Reflection;
using System.Threading;

namespace RSSRadio
{
	class CoolItem
	{
        private string iconResourceString;
        private string iconResourceString32;
        public string Title;
		public string Description;
        /// <summary>
        /// This proparty can be used to store custom info
        /// </summary>
        public string Tag;

        public void setIconResourceStrings(String iconResourceString,String iconResourceString32)
        {
            this.iconResourceString = iconResourceString;
            this.iconResourceString32 = iconResourceString32;
        }

        public string IconResourceString
        {
            get { return iconResourceString; }
        }
        public string IconResourceString32
        {
            get { return iconResourceString32; }
        }
        public string getIconResourceString(bool bigPricutre)
        {
            return bigPricutre? iconResourceString32: IconResourceString;

        }
    
    
    }

	public class CoolListView : Control
	{
		protected VScrollBar ScrollBar;
		public ArrayList Items;
		public int selectedItemIndex;
		protected Bitmap ListRendering;
		protected int DrawWidth;
		protected int MaxDisplayableItems;
		protected int ItemHeightPixels = 34; // constant unless OnPaint is modified or overridden

        public event EventHandler<EventArgs> SelectedItemChanged;

        public CoolListView()
		{
			Items = new ArrayList();

			ScrollBar = new VScrollBar();
			ScrollBar.Parent = this;
			ScrollBar.Dock = DockStyle.Right;

			SelectedItemIndex = 0;

			this.Resize += new EventHandler(CoolListView_Resize);
			this.KeyDown += new KeyEventHandler(CoolListView_KeyDown);

			ScrollBar.ValueChanged += new EventHandler(ScrollBar_ValueChanged);
			ScrollBar.LargeChange = 1;
			ScrollBar.Maximum = 0;

            float fontHeightBold = 10;
            float fontHeightRegular = 11;
            Font tahomaBold = new Font("Tahoma", 10.0F, FontStyle.Bold);
            Font tahomaReg = new Font("Tahoma", 10.0F, FontStyle.Regular);
            Graphics g = this.CreateGraphics();
            try
            {
                fontHeightBold = g.MeasureString("M", tahomaBold).Height;
                fontHeightRegular = g.MeasureString("M", tahomaReg).Height;
            }
            finally
            {
                g.Dispose();
                tahomaBold.Dispose();
                tahomaReg.Dispose();
            }
            ItemHeightPixels = (int)(Math.Ceiling( fontHeightBold + fontHeightRegular)) + 2;
            MaxDisplayableItems = this.Height / ItemHeightPixels;
		}

		private void CoolListView_KeyDown(object sender, KeyEventArgs e)
		{
            ProxyKeyDown(e);
		}

        public virtual void ProxyKeyDown(KeyEventArgs e)
        {
            if (Items.Count == 0)
                return;

            // handle Up on the joystick
            if (e.KeyCode == Keys.Up && SelectedItemIndex > 0)
            {
                if (ScrollBar.Value > 0 && SelectedItemIndex - ScrollBar.Value == 0)
                    ScrollBar.Value--;

                SelectedItemIndex--;
            }

            // handle Down on the joystick
            else if (e.KeyCode == Keys.Down && SelectedItemIndex < Items.Count - 1)
            {
                if (SelectedItemIndex - ScrollBar.Value == MaxDisplayableItems - 1)
                    ScrollBar.Value++;

                SelectedItemIndex++;
            }

            this.Refresh();
        }

		protected void ScrollBar_ValueChanged(object sender, EventArgs e)
		{
			this.Refresh();
		}

		protected void CoolListView_Resize(object sender, EventArgs e)
		{
			MaxDisplayableItems = this.Height / ItemHeightPixels;

			if (ScrollBar.Visible)
				DrawWidth = ScrollBar.Location.X;
			else
				DrawWidth = this.Width;

			ListRendering = new Bitmap(DrawWidth, this.Height);
		}

		protected override void OnPaint(PaintEventArgs e)
		{
			if (Items.Count == 0)
			{
				e.Graphics.Clear(Color.White);
				return;
			}

			ScrollBar.Maximum = (Items.Count > MaxDisplayableItems) ? (Items.Count - MaxDisplayableItems) : 0;

			Graphics drawTool = Graphics.FromImage(ListRendering);
			drawTool.Clear(Color.White);

			// draw the highlight for the user-selected item.
			if (!(SelectedItemIndex - ScrollBar.Value == MaxDisplayableItems)) // prevent highlighting the lowest list row which may be partially on the screen
			{
                using (SolidBrush highlightBrush = new SolidBrush(SystemColors.Highlight))
                {
                    drawTool.FillRectangle(highlightBrush, 0, 1 + ((SelectedItemIndex - ScrollBar.Value) * ItemHeightPixels), DrawWidth, ItemHeightPixels);
                }
            }

			// draw each item's title, description, and icon
			Pen grayPen = new Pen(Color.DarkGray);
            SolidBrush blackBrush = new SolidBrush(Color.Black);
            Font tahomaBold = new Font("Tahoma", 10.0F, FontStyle.Bold);
			Font tahomaReg = new Font("Tahoma", 10.0F, FontStyle.Regular);
            try
            {
                int fontHeightBold = (int)drawTool.MeasureString("M", tahomaBold).Height;
                int fontHeightRegular = (int)drawTool.MeasureString("M", tahomaReg).Height;

                int x = 23; 
                int y = 1;
                bool bigScreen = false;
                //Allow space for big icons on big screens
                if (this.Width > 400)
                {
                    bigScreen = true;
                    x += 16;
                }

                
                int maximum = (Items.Count <= MaxDisplayableItems) ? Items.Count : ScrollBar.Value + MaxDisplayableItems;
                for (int i = ScrollBar.Value; i < maximum; i++)
                {
                    // draw icon
                    string iconResource = ((CoolItem)Items[i]).getIconResourceString(bigScreen);
                    Bitmap icon = new Bitmap(Assembly.GetExecutingAssembly().GetManifestResourceStream(iconResource));
                    ImageAttributes ia = new ImageAttributes();
                    ia.SetColorKey(Color.Red, Color.Red);
                    drawTool.DrawImage(icon, new Rectangle(2, y + 3, icon.Width, icon.Height), 0, 0, icon.Width, icon.Height, GraphicsUnit.Pixel, ia);

                    // draw title
                    drawTool.DrawString(((CoolItem)Items[i]).Title, tahomaBold, blackBrush, x, y);
                    y += fontHeightBold - 1 ;

                    // draw description
                    drawTool.DrawString(((CoolItem)Items[i]).Description, tahomaReg, blackBrush, x, y);
                    y += fontHeightRegular + 2;

                    // draw separator
                    drawTool.DrawLine(grayPen, 0, y, DrawWidth, y++);
                }
            }
            finally
            {
                drawTool.Dispose();
                grayPen.Dispose();
                tahomaReg.Dispose();
                tahomaBold.Dispose();
                blackBrush.Dispose();
            }
			e.Graphics.DrawImage(ListRendering, 0, 0);
		}

		//protected void CoolListView_MouseDown(object sender, MouseEventArgs e)
		//{
		//    int itemIndex = (e.Y / ItemDisplayHeight) + ScrollBar.Value;
		//    if (itemIndex < ScrollBar.Value + MaxDisplayableItems)
		//        SelectedItemIndex = itemIndex;

		//    this.Refresh();
		//}

		/// <summary> 
		/// Paints the background of the control. Overriden to prevent flicker. 
		/// </summary> 
		/// <remarks>
		/// from http://groups.google.com/group/microsoft.public.dotnet.framework.compactframework/msg/002888f042ce740f?&q=custom+control+flickers+%22pocket+pc%22
		/// </remarks>
		protected override void OnPaintBackground(System.Windows.Forms.PaintEventArgs e)
		{
			// Override and do nothing to prevent flicker. 
		}

		public override void Refresh()
		{
			if (SelectedItemIndex >= Items.Count)
				SelectedItemIndex = 0;

			base.Refresh();
		}

        protected virtual void SelectedItemIndexChanged()
        {
            if (SelectedItemChanged != null)
            {
                SelectedItemChanged(this, new EventArgs());
            }
        }

        public int SelectedItemIndex
        {
            get { return this.selectedItemIndex; }
            set 
            {
                if (selectedItemIndex != value)
                {
                    selectedItemIndex = value;
                    if (Items.Count > 0 && SelectedItemIndex >= 0 && SelectedItemIndex < Items.Count)
                    {
                        SelectedItemIndexChanged();
                    }
                }
            }
        }
	}
}
